package cz.kralicko.main.dao;

import java.util.Collection;
import java.util.List;

import org.hibernate.ObjectNotFoundException;


public interface GenericDao<T> {

	/** Maximal range size. */
	int MAXIMAL_RECORD_COUNT = 1000;

	/** Maximal in size. */
	int MAXIMAL_IN_COUNT = 1000;

	/**
	 * Get entity by id.
	 * 
	 * @param id
	 *            id of entity
	 * @return desired entity
	 * @throws ObjectNotFoundException
	 *             if entity with given id is not found.
	 * @throws cz.zcu.kiv.db2.exceptions.ObjectNotFoundException
	 */
	T getById(long id);

	/**
	 * Get all entities of concrete type.
	 * 
	 * @return list of entities
	 */
	List<T> getAll();

	/**
	 * Get all entities of concrete type sorted by given attribute.
	 * 
	 * @param sortedBy
	 *            name of attribute to sort by
	 * @return list of entities
	 */
	List<T> getAll(String sortedBy);

	/**
	 * Store entity into storage.
	 * 
	 * @param entity
	 *            the entity to store
	 * @return stored entity
	 * @throws BadAttributesException
	 */
	T store(T entity);

	/**
	 * Merge entity into storage.
	 * 
	 * @param entity
	 *            the entity to merge
	 * @return merged entity
	 */
	T merge(T entity);

	/**
	 * Store (insert) unsaved entity in storage.
	 * 
	 * @param entity
	 *            the entity to save
	 * @return created entity
	 */
	T save(T entity);

	/**
	 * Delete entity from storage.
	 * 
	 * @param entity
	 *            the entity to delete
	 */
	void delete(final T entity);

	/**
	 * Does flush.
	 */
	void flush();

	/**
	 * Count entities.
	 * 
	 * @return count all of target entity in db
	 */
	Integer count();

	/**
	 * Removes proxy from object. {@linkplain http
	 * ://forum.hibernate.org/viewtopic
	 * .php?p=2316854&sid=32510992b3c53568f4f14a7354767e7d}
	 * 
	 * @param <S>
	 *            class of target object
	 * @param maybeProxy
	 *            probably proxied object
	 * @param baseClass
	 *            target class to retype to
	 * @return deproxied object
	 * @throws ClassCastException
	 *             ...
	 */
	<S> S deproxy(Object maybeProxy, Class<S> baseClass)
			throws ClassCastException;

	/**
	 * Removes proxy from object. {@linkplain http
	 * ://forum.hibernate.org/viewtopic
	 * .php?p=2316854&sid=32510992b3c53568f4f14a7354767e7d}
	 * 
	 * @param maybeProxy
	 *            probably proxied object
	 * @return deproxied object
	 * @throws ClassCastException
	 *             ...
	 */
	T deproxy(Object maybeProxy) throws ClassCastException;

	/**
	 * Removes entity from DB cache.
	 * 
	 * @param entity
	 *            to be removed from DB cache
	 */
	void evict(T entity);

	void deleteAll(Collection<T> collection);

	void afterPropertiesSet() throws Exception;

	T getFirst();

	T getLast();
}
